/**
 * 
 */
package org.swing.utility.system.log;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.swing.utility.system.config.Configuration;
import org.swing.utility.system.file.FileUtil;
import org.swing.utility.system.thread.ThreadLocalMap;

/**
 * @author lqnhu
 *
 */
public class TrafficLogger {
	static String trafficDir;
	static {
		String logsRoot = Configuration.getLogsRoot();
		trafficDir = logsRoot + "/traffic";
	}

	private String reqFileName;
	private File threadDir;
	private final String type;
	private final boolean log;
	private final Date time;

	public TrafficLogger(String reqFileName, String type, boolean log,
			final Date time) {
		this.type = type;
		this.log = log;
		this.time = time;
		if (log)
			init(reqFileName);
	}

	private void init(String reqFileName) {
		this.reqFileName = FileUtil.cleanFileName(reqFileName);
		this.threadDir = getThreadDir();
	}

	protected synchronized String createThreadId() {
		return new SimpleDateFormat("HH_mm_ss_SSS").format(time);
	}

	private void storeRequestHeader(byte[] bytes) {
		store(bytes, "request.header_" + type + ".txt");
	}

	private void storeRequestBody(byte[] bytes) {
		store(bytes, "request.body_" + type + ".txt");
	}

	private void storeResponseHeader(byte[] bytes) {
		store(bytes, "response.header_" + type + ".txt");
	}

	private void storeResponseBody(byte[] bytes) {
		store(bytes, "response.body" + "_" + type
				+ (reqFileName == null ? "" : "_" + reqFileName));
	}

	private void store(byte[] bytes, String fileName) {
		if (!log)
			return;
		if (bytes == null)
			return;
		File file = new File(threadDir, fileName);
		FileOutputStream out = null;
		try {
			if (!file.exists())
				file.createNewFile();
			out = new FileOutputStream(file, true);
			out.write(bytes);
			out.flush();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (out != null)
					out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	private File getThreadDir() {
		String threadId = createThreadId();
		File threadDir = new File(trafficDir + "/"
				+ (new SimpleDateFormat("yyyy_MM_dd").format(time)) + "/"
				+ threadId + (reqFileName == null ? "" : "_" + reqFileName));
		threadDir.mkdirs();
		return threadDir;
	}

	public static TrafficLogger getLoggerForThread(String type) {
		return (TrafficLogger) ThreadLocalMap.get("logger_" + type);
	}

	public static void createLoggerForThread(String fileName, String type,
			boolean log, Date time) {
		TrafficLogger logger = new TrafficLogger(fileName, type, log, time);
		ThreadLocalMap.put("logger_" + type, logger);
	}

	public static void storeRequestHeader(byte[] bytes, String type) {
		final TrafficLogger loggerForThread = getLoggerForThread(type);
		if (loggerForThread != null)
			loggerForThread.storeRequestHeader(bytes);
	}

	public static void storeRequestBody(byte[] bytes, String type) {
		final TrafficLogger loggerForThread = getLoggerForThread(type);
		if (loggerForThread != null)
			loggerForThread.storeRequestBody(bytes);
	}

	public static void storeResponseHeader(byte[] bytes, String type) {
		final TrafficLogger loggerForThread = getLoggerForThread(type);
		if (loggerForThread != null)
			loggerForThread.storeResponseHeader(bytes);
	}

	public static void storeResponseBody(byte[] bytes, String type) {
		final TrafficLogger loggerForThread = getLoggerForThread(type);
		if (loggerForThread != null)
			loggerForThread.storeResponseBody(bytes);
	}
}


